package com.ifcar.app.fragment;

import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.widget.Toast;

import com.ifcar.app.util.StringUtil;
import com.ifcar.app.util.Tools;
import com.ifcar.app.activity.R;

public class NRLoadingFrament extends NRFragment {
	public static final int MSG_REFRESHING = 8106;

	public static final int MSG_LOADING = MSG_REFRESHING + 1;

	public static final int MSG_LOADING_MORE = MSG_LOADING + 1;

	public static final int SUCCESSED = 0;

	public static final int ERROR_TYPE_NET = 8106;
	
	public static final int ERROR_TYPE_DETACHED = ERROR_TYPE_NET + 1;

	private String mRefreshTag;

	private boolean mInLoading;

	private boolean mInRefreshing;

	private boolean mInLoadingMore;

	private int mStart = 0;

	private int mLoadingNum = 20;

	public int getLoadingNum() {
		return mLoadingNum;
	}

	public void setLoadingNum(int num) {
		mLoadingNum = num;
	}

	public int getLoadingStart() {
		return mStart;
	}
	
	void setLoadingStart(int start) {
		mStart = start;
	}

	public Handler getHandler() {
		return mHandler;
	}

	private Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
		    if (!isAdded()) {
		        return;
		    }
		    if (onInterpreterHandleMessage(msg)) {
				return;
			}
			NRLoadingFrament.this.handleMessage(msg);
		}
	};

	/**
	 * 通过覆盖本方法可以优先处理getHandler()的msg
	 * 
	 * @param msg
	 * @return 返回true表示已经处理,不会再传到handleMessage
	 */
	boolean onInterpreterHandleMessage(Message msg) {
		switch (msg.what) {
		case MSG_LOADING: {
			handleLoading(msg.obj);
			return true;
		}
		case MSG_REFRESHING: {
			handleRefreshing(msg.obj);
			return true;
		}
		case MSG_LOADING_MORE: {
			handleLoadingMore(msg.obj);
			return true;
		}
		default:
			break;
		}
		return false;
	}

	/**
	 * 子类可以直接调用getHandler使用handler,通过覆盖本方法处理回调
	 * 
	 * @param msg
	 */
	public void handleMessage(Message msg) {

	}

	/**
	 * 判断是否已经超过刷新时间
	 * 
	 * @return
	 */
	public boolean isNeedRefresh() {
		if (mInRefreshing || !isAdded() || TextUtils.isEmpty(mRefreshTag)) {
			return false;
		}
		return StringUtil.isNeedRefresh(getActivity(), mRefreshTag);
	}

	/**
	 * 返回刷新tag
	 * 
	 * @return
	 */
	public String getRefreshTag() {
		return mRefreshTag;
	}

	/**
	 * 设置刷新tag, 在显示和判断刷新时间间隔有用
	 * 
	 * @param tag
	 */
	public void setRefreshTag(String tag) {
		mRefreshTag = tag;
	}

	/**
	 * *********************************************************
	 */

	/**
	 * 是否正在加载
	 * 
	 * @return
	 */
	public final boolean inLoading() {
		return mInLoading;
	}

	/**
	 * 执行加载操作
	 */
	public void startLoading() {
		if (mInLoading) {
			return;
		}

		int type = canLoading();
		if (type == SUCCESSED) {
			mInLoading = true;
			showProgress();
			onLoading();
		} else {
			onLoadingError(type);
		}

	}

	/**
	 * 子类覆盖此方法执行真正加载
	 */
	protected void onLoading() {

	}

	/**
	 * 当{@link #canLoading()} 没有返回 {@link #SUCCESSED}会调用此方法<br/>
	 * 
	 * @param type
	 */
	protected void onLoadingError(int type) {
		switch (type) {
		case ERROR_TYPE_NET:
			Toast.makeText(getActivity(), R.string.msg_net_error,
					Toast.LENGTH_SHORT).show();
			break;

		default:
			break;
		}
	}

	/**
	 * 检测是否能进行刷新<br/>
	 * 默认返回{@link SUCCESSED},子类覆盖此方法对更多条件进行判断<br/>
	 * 
	 * @return {@link SUCCESSED}
	 */
	protected int canLoading() {
		if (!isAdded()) {
			return ERROR_TYPE_DETACHED;
		}
		return SUCCESSED;
	}

	/**
	 * 对加载的结果执行操作
	 */
	protected void handleLoading(Object result) {
		mInLoading = false;
		if(!isAdded()) {
            return;
        }
		if (checkLoadingProgress()) {
			showProgress();
		} else {
			hideProgress();
		}
		onHandleLoading(result);
	}

	/**
	 * 子类覆盖此方法,真正执行对加载结果的操作
	 */
	protected void onHandleLoading(Object result) {

	}

	/**
	 * *********************************************************
	 */

	/**
	 * 是否正在刷新
	 */
	public final boolean inRefreshing() {
		return mInRefreshing;
	}

	/**
	 * 执行刷新操作
	 */
	public void refresh() {
		refreshInternal(true);
	}

	/**
	 * 执行刷新操作
	 * 
	 * @param callError
	 *            为false时,当{@link #canRefreshing()} 返回错误时不调用
	 *            {@link #onRefreshingError(int)}方法
	 */
	private void refreshInternal(boolean callError) {
		if (mInRefreshing) {
			return;
		}

		int type = canRefreshing();
		if (type == SUCCESSED) {
			mInRefreshing = true;
			showProgress();
			onRefreshing();
		} else if (callError) {
			onRefreshingError(type);
		}
	}

	/**
	 * 子类覆盖此方法执行真正刷新
	 */
	protected void onRefreshing() {

	}

	/**
	 * 当{@link #canRefreshing()} 没有返回 {@link #SUCCESSED}会调用此方法<br/>
	 * 
	 * @param type
	 */
	protected void onRefreshingError(int type) {
		switch (type) {
		case ERROR_TYPE_NET:
			Toast.makeText(getActivity(), R.string.msg_net_error,
					Toast.LENGTH_SHORT).show();
			break;

		default:
			break;
		}
	}

	/**
	 * 检测是否能进行刷新<br/>
	 * 默认只进行网络判断,子类覆盖此方法对更多条件进行判断<br/>
	 * 
	 * @return {@link SUCCESSED} 或者 {@link ERROR_TYPE_NET}...
	 */
	protected int canRefreshing() {
		if (!isAdded()) {
			return ERROR_TYPE_DETACHED;
		}
		if (!Tools.CheckNetwork(getActivity())) {
			return ERROR_TYPE_NET;
		}
		return SUCCESSED;
	}

	/**
	 * 对刷新的结果执行操作
	 */
	protected void handleRefreshing(Object result) {
		mInRefreshing = false;
		if(!isAdded()) {
            return;
        }
		if (checkLoadingProgress()) {
			showProgress();
		} else {
			hideProgress();
		}
		onHandleRefreshing(result);
	}

	/**
	 * 子类覆盖此方法,真正执行对刷新结果的操作
	 */
	protected void onHandleRefreshing(Object result) {

	}

	/**
	 * 是否正在加载更多
	 * 
	 * @return
	 */
	public final boolean inLoadingMore() {
		return mInLoadingMore;
	}

	/**
	 * 执行加载更多操作
	 */
	public void startLoadingMore() {
		if (mInLoadingMore) {
			return;
		}

		int type = canLoadingMore();
		if (type == SUCCESSED) {
			mInLoadingMore = true;
			showProgress();
			onLoadingMore();
		} else {
			onLoadingMoreError(type);
		}

	}

	/**
	 * 子类覆盖此方法执行真正加载更多
	 */
	protected void onLoadingMore() {

	}

	/**
	 * 当{@link #canLoadingMore()} 没有返回 {@link #SUCCESSED}会调用此方法<br/>
	 * 
	 * @param type
	 */
	protected void onLoadingMoreError(int type) {
		switch (type) {
		case ERROR_TYPE_NET:
			Toast.makeText(getActivity(), R.string.msg_net_error,
					Toast.LENGTH_SHORT).show();
			break;

		default:
			break;
		}
	}

	/**
	 * 检测是否能进行刷新<br/>
	 * 默认只进行网络判断,子类覆盖此方法对更多条件进行判断<br/>
	 * 
	 * @return {@link SUCCESSED}
	 */
	protected int canLoadingMore() {
		if (!isAdded()) {
			return ERROR_TYPE_DETACHED;
		}
		if (!Tools.CheckNetwork(getActivity())) {
			return ERROR_TYPE_NET;
		}
		return SUCCESSED;
	}

	/**
	 * 对加载的结果执行操作
	 */
	protected void handleLoadingMore(Object result) {
		mInLoadingMore = false;
		if(!isAdded()) {
            return;
        }
		if (checkLoadingProgress()) {
			showProgress();
		} else {
			hideProgress();
		}
		onHandleLoadingMore(result);
	}

	/**
	 * 子类覆盖此方法,真正执行对加载结果的操作
	 */
	protected void onHandleLoadingMore(Object result) {

	}

	protected boolean checkLoadingProgress() {
		return mInLoading || mInRefreshing || mInLoadingMore;
	}

	@Override
	public void onTabSelected(boolean first) {
		super.onTabSelected(first);

		if (first && autoRefreshOnFirst()) {
			refresh();
		} else if (!first && isNeedRefresh()) {
			// refreshInternal(false);
		    mHandler.removeCallbacks(mAutoRefreshRunnable);
			mHandler.postDelayed(mAutoRefreshRunnable, 200);
		}

		if (checkLoadingProgress()) {
			showProgress();
		} else {
			hideProgress();
		}
	}
	
	   @Override
    public void onTabUnSelected() {
        super.onTabUnSelected();
        hideProgress();
    }
	
	@Override
	public void onResume() {
	    super.onResume();
	    if (inTabSelected() && isNeedRefresh()) {
	        mHandler.removeCallbacks(mAutoRefreshRunnable);
            mHandler.postDelayed(mAutoRefreshRunnable, 200);
	    }
	    
        if (checkLoadingProgress()) {
            showProgress();
        } else {
            hideProgress();
        }
	}

	protected boolean autoRefreshOnFirst() {
		return false;
	}

	private Runnable mAutoRefreshRunnable = new Runnable() {
		@Override
		public void run() {
			refreshInternal(false);
		}
	};
}
